<template>
  <div class="content-block">
    <div class="info-head">
      {{ title }}
    </div>
    <div class="info-content">
      <div class="padding">
        <el-radio-group v-model="chartType">
          <el-radio-button
            v-for="item in chartTypeOptions" :key="item.value"
            :label="item.value"
          >
            {{item.name}}
          </el-radio-button>
        </el-radio-group>
      </div>
      <div class="flex">
        <div class="lines-block">
          <line-chart
            ref="chart" :unit-name="unitName"
            :title="lineTitle" :height="height" :show-legend="showLegend"
            :x-data="linesXData" :y-data="linesYData" :lines="lines"
            :download-func="exportLinesData"
          ></line-chart>
        </div>
        <div class="pie-block" :style="{height: height}">
          <pie-chart
            ref="pie" :title="pieTitle" :data="pieData"
            :download-func="exportPieData"
          ></pie-chart>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import {
  CHART_DAILY, CHART_MONTHLY, CHART_ANNUAL,
} from '@/utils/constant'
import {
  WATER, ELECTRIC, GAS, COAL, OTHER,
  WATER_TEXT, ELECTRIC_TEXT, GAS_TEXT, COAL_TEXT, OTHER_TEXT,
} from '@/config'
import { utils, writeFile } from 'xlsx-js-style'
import LineChart from '@/views/data-presentation-overview/line-chart'
import PieChart from '@/views/data-presentation-overview/pie-chart'
import { simpleJson2Sheet } from '@/utils/sheet'
import {
  loadDayWaterList, loadDayElectricityList, loadDayGasList,
  loadMonthWaterList, loadMonthElectricityList, loadMonthGasList,
  loadEnergyTypeTrends as _loadEnergyTypeTrends,

  loadMonthList as _loadMonthList,
  loadDayList as _loadDayList,

  selectDayConsumeTopThree,
  selectMonthConsumeTopThree,
  selectYearConsumeTopThree,
} from '@/api/energyDataManagement'

function loadEnergyTypeTrends (type) {
  return function () {
    return _loadEnergyTypeTrends(type)
  }
}
function loadDayList (type) {
  return function () {
    return _loadDayList(type)
  }
}
function loadMonthList (type) {
  return function () {
    return _loadMonthList(type)
  }
}

const LINES_METHODS = {
  [CHART_DAILY]: {
    [WATER]: loadDayWaterList,
    [ELECTRIC]: loadDayElectricityList,
    [GAS]: loadDayGasList,
    [COAL]: loadDayList(COAL),
    [OTHER]: loadDayList(OTHER),
  },
  [CHART_MONTHLY]: {
    [WATER]: loadMonthWaterList,
    [ELECTRIC]: loadMonthElectricityList,
    [GAS]: loadMonthGasList,
    [COAL]: loadMonthList(COAL),
    [OTHER]: loadMonthList(OTHER),
  },
  [CHART_ANNUAL]: {
    [WATER]: loadEnergyTypeTrends(WATER),
    [ELECTRIC]: loadEnergyTypeTrends(ELECTRIC),
    [GAS]: loadEnergyTypeTrends(GAS),
    [COAL]: loadEnergyTypeTrends(COAL),
    [OTHER]: loadEnergyTypeTrends(OTHER),
  },
}
const PIE_METHODS = {
  [CHART_DAILY]: selectDayConsumeTopThree,
  [CHART_MONTHLY]: selectMonthConsumeTopThree,
  [CHART_ANNUAL]: selectYearConsumeTopThree,
}
export default {
  name: 'focus-energy',
  components: { LineChart, PieChart },
  props: {
    title: String,
    height: {
      type: String,
      default: '80vh'
    },
    type: {
      type: String,
      required: true,
      validator (value) {
        return [WATER, ELECTRIC, GAS, COAL, OTHER].indexOf(value) > -1
      }
    },
    typeText: {
      type: String,
      validator (value) {
        return [WATER_TEXT, ELECTRIC_TEXT, GAS_TEXT, COAL_TEXT, OTHER_TEXT].indexOf(value) > -1
      }
    }
  },
  data () {
    return {
      chartType: CHART_DAILY,
      chartTypeOptions: [
        { name: '日度耗用', value: CHART_DAILY },
        { name: '月度耗用', value: CHART_MONTHLY },
        { name: '年度耗用', value: CHART_ANNUAL },
      ],

      linesData: [],
      pieData: [],

      year: new Date().getFullYear(),
      prevMonth: this.$dayjs().month(),
      prevDate: this.$dayjs().subtract(1, 'day').date()
    }
  },
  computed: {
    lineTitle () {
      const { chartType, typeText, year } = this
      if (chartType === CHART_DAILY) {
        return `${year}年日${typeText}数据图`
      }
      if (chartType === CHART_MONTHLY) {
        return `${year}年每月${typeText}数据图`
      }
      if (chartType === CHART_ANNUAL) {
        return `${year}年${typeText}月累积数据图`
      }
      return ''
    },
    pieTitle () {
      const { chartType, typeText, year, prevMonth, prevDate } = this
      if (chartType === CHART_DAILY) {
        return `${prevDate}日企业${typeText}排行前五`
      }
      if (chartType === CHART_MONTHLY) {
        return `${prevMonth}月企业${typeText}排行前五`
      }
      if (chartType === CHART_ANNUAL) {
        return `${year}年企业${typeText}排行前五`
      }
      return ''
    },
    lines () {
      const { linesData, chartType } = this
      if (chartType === CHART_DAILY) {
        return linesData.map(v => {
          const m = (v.dataTime || '').match(/\d{4}-(\d{2})/) || []
          return m[1] + '月'
        })
      }
      if (chartType === CHART_MONTHLY) {
        return [`${this.year}年${this.prevMonth}月`]
      }
      if (chartType === CHART_ANNUAL) {
        return [`${this.year}年`]
      }
      return []
    },
    showLegend () {
      const { chartType } = this
      return chartType === CHART_DAILY
    },
    linesXData () {
      const { chartType } = this
      if (chartType === CHART_DAILY) {
        return Array(31).fill(1).map((v, i) => (i + 1) + '日')
      }
      if (chartType === CHART_MONTHLY || chartType === CHART_ANNUAL) {
        return Array(12).fill(1).map((v, i) => (i + 1) + '月')
      }
      return []
    },
    linesYData () {
      const { linesData, chartType } = this
      if (chartType === CHART_DAILY) {
        return linesData.map(v => {
          const length = this.$dayjs(v.dataTime).daysInMonth()
          const array = Array(length).fill(null)
          const list = v.list || []
          list.forEach(vv => {
            const m = (vv.dataTime || '').match(/\d{4}-\d{2}-(\d{2})/)
            if (m) {
              const index = +(m[1]) - 1
              array.splice(index, 1, +vv.val)
            }
          })
          return array
        })
      }
      if (chartType === CHART_MONTHLY || chartType === CHART_ANNUAL) {
        const result = Array(this.linesXData.length).fill(null)
        linesData.forEach((v, i) => {
          const m = (v.name || '').replace(/\d{4}-(\d{2})/, (p, m) => m)
          result.splice(Number(m) - 1, 1, v.val ? Number(v.val).toFixed(2) : null)
        })
        return [result]
      }
      return []
    },
    unitName () {
      const energyUnits = this.$store.state.energyUnits
      const type = this.type
      const target = energyUnits.find(v => v.key === type)
      return target ? target.value : '吨标准煤'
    },
    loadLinesList () {
      const type = this.type
      const chartType = this.chartType
      return LINES_METHODS[chartType][type]
    },
    loadPieList () {
      const chartType = this.chartType
      return PIE_METHODS[chartType]
    },
  },
  watch: {
    chartType () {
      this.queryLinesData()
      this.queryPieData()
    },
  },
  mounted () {
    this.queryLinesData()
    this.queryPieData()
  },
  methods: {
    queryLinesData () {
      this.$refs.chart && this.$refs.chart.setLoading(true)
      const loadLinesList = this.loadLinesList || Promise.resolve()
      return loadLinesList().then(res => {
        if (res.code === 200) {
          res.data = res.data || []
          this.linesData = Array.isArray(res.data) ? res.data : [res.data]
        }
      }).finally(() => {
        this.$refs.chart && this.$refs.chart.setLoading(false)
      })
    },
    exportLinesData () {
      const linesData = this.linesData
      const unitName = this.unitName
      const typeText = this.typeText
      const lineTitle = this.lineTitle
      const headers = [['日期', `${typeText}（${unitName}）`]]
      const fileName = `${lineTitle}.xlsx`
      const workbook = utils.book_new()
      if (linesData[0] && linesData[0].list !== undefined) {
        linesData.forEach((v, i) => {
          const sheetName = v.dataTime
          const data = (v.list || []).map(vv => ({
            dataTime: vv.dataTime,
            val: vv.val
          }))
          const worksheet = utils.json_to_sheet(data)
          utils.book_append_sheet(workbook, worksheet, sheetName || 'sheet' + (i + 1))
          utils.sheet_add_aoa(worksheet, headers, { origin: 'A1' })

          /* calculate column width */
          const maxWidth1 = data.reduce((w, r) => Math.max(w, String(r.dataTime).length), 15);
          const maxWidth2 = data.reduce((w, r) => Math.max(w, String(r.val).length), 15);
          worksheet['!cols'] = [{ wch: maxWidth1 }, { wch: maxWidth2 }];
        })
      } else {
        const worksheet = utils.json_to_sheet(linesData)
        utils.book_append_sheet(workbook, worksheet, lineTitle || 'sheet1')
        utils.sheet_add_aoa(worksheet, headers, { origin: 'A1' })

        const maxWidth1 = linesData.reduce((w, r) => Math.max(w, String(r.name).length), 15);
        const maxWidth2 = linesData.reduce((w, r) => Math.max(w, String(r.val).length), 15);
        worksheet['!cols'] = [{ wch: maxWidth1 }, { wch: maxWidth2 }];
      }

      writeFile(workbook, fileName, { compression: true })
    },
    exportPieData () {
      const pieTitle = this.pieTitle
      const typeText = this.typeText
      const fileName = `${pieTitle}.xlsx`
      const headers = [['企业名称', `${typeText}（${this.unitName}）`]]
      const data = this.pieData
      simpleJson2Sheet(fileName, headers, data, pieTitle)
    },
    queryPieData () {
      this.$refs.pie && this.$refs.pie.setLoading(true)
      const loadPieList = this.loadPieList
      return loadPieList(this.type).then(res => {
        if (res.code === 200) {
          this.pieData = (res.data || []).map(v => ({
            name: v.name,
            value: v.val
          }))
        }
      }).finally(() => {
        this.$refs.pie && this.$refs.pie.setLoading(false)
      })
    },
  },
}
</script>

<style scoped>
.lines-block {
  flex: 1 0 67%;
}
.pie-block {
  flex: 0 0 33%;
}
</style>
